package cn.com.cetccst.activation.ui.viewmodel;

import static cn.com.cetccst.activation.network.response.FeaturesResponse.Feature.FEATURE_CA;
import static cn.com.cetccst.activation.network.response.FeaturesResponse.Feature.FEATURE_MAM;
import static cn.com.cetccst.activation.network.response.FeaturesResponse.Feature.FEATURE_MDM;
import static cn.com.cetccst.activation.network.response.FeaturesResponse.Feature.FEATURE_VPN;
import static cn.com.cetccst.tools.kv.CommonKV.kvStore;

import android.content.Context;
import android.util.Base64;

import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;

import com.google.gson.Gson;
import com.google.gson.annotations.SerializedName;

import java.util.Objects;

import cn.com.cetccst.activation.ActivationManager;
import cn.com.cetccst.activation.R;
import cn.com.cetccst.activation.kv.KVKeys;
import cn.com.cetccst.activation.network.ActivationHttpRequester;
import cn.com.cetccst.activation.network.response.AuthCodeResponse;
import cn.com.cetccst.activation.network.response.FeaturesResponse;
import cn.com.cetccst.activation.network.response.MAMSSOResponse;
import cn.com.cetccst.activation.network.response.MDMSSOResponse;
import cn.com.cetccst.tools.log.CommonLogger;
import cn.com.cetccst.tools.phone.Phone;
import rx.Observable;
import rx.Observer;
import rx.functions.Func1;

public class RegisterViewModel extends ViewModel {

    public MutableLiveData<String> prompt = new MutableLiveData<>();
    public MutableLiveData<Boolean> failure = new MutableLiveData<>();

    public void requestFeatures(Context context) {

        prompt.setValue("正在注册模块......");
        ActivationHttpRequester.getInstance().requestFeatures()
                .flatMap((Func1<FeaturesResponse, Observable<FeaturesResponse.Feature>>) featuresResponse -> {
                    if (featuresResponse.getErrCode() == 0) {
                        return Observable.from(featuresResponse.getFeatures());
                    }
                    throw new RuntimeException("请求错误");
                })
                .filter(feature -> Objects.equals(feature.getStatus(), FeaturesResponse.Feature.ENABLE))
                .concatMap((Func1<FeaturesResponse.Feature, Observable<AuthResult>>) feature -> {
                    switch (feature.getFeature()) {
                        case FEATURE_MDM -> {
                            prompt.setValue("MDM模块注册中...");
                            return ActivationHttpRequester.getInstance().requestAuthCode(context, context.getPackageName(), context.getString(R.string.sso_reg_id)).
                                    flatMap((Func1<AuthCodeResponse, Observable<MDMSSOResponse>>) authCodeResponse ->
                                            ActivationHttpRequester.getInstance().requestMDMSSO(context, kvStore.decodeString(KVKeys.KEY_USER_ID), authCodeResponse.getOauthCode()))
                                    .map(ssoResponse -> {
                                        String finalProvisionResponseConfig = new String(Base64.decode(ssoResponse.getProvisionResponseConfig(), Base64.NO_WRAP));
                                        //TODO MDM相关信息的持久化
                                        MDMConfig config = new Gson().fromJson(finalProvisionResponseConfig, MDMConfig.class);
                                        kvStore.encode(KVKeys.KEY_MDM_TOKEN, config.token);
                                        AuthResult result = new AuthResult(feature);
                                        result.setResult(true);
                                        return result;
                                    });
                        }
                        case FEATURE_MAM -> {
                            prompt.setValue("MAM模块注册中...");
                            return ActivationHttpRequester.getInstance().requestAuthCode(context, "com.zdk.mg.mgstore", context.getString(R.string.sso_mam_reg_id)).
                                    flatMap((Func1<AuthCodeResponse, Observable<MAMSSOResponse>>) authCodeResponse ->
                                            ActivationHttpRequester.getInstance().requestMAMSSO(context, authCodeResponse.getOauthCode()))
                                    .map(ssoResponse -> {
                                        String token = ssoResponse.getAccess_token();
                                        //TODO 处理MAM token
                                        kvStore.encode(KVKeys.KEY_MAM_TOKEN, token);
                                        AuthResult result = new AuthResult(feature);
                                        result.setResult(true);
                                        return result;
                                    });
                        }
                        case FEATURE_VPN, FEATURE_CA -> {
                            prompt.setValue("其它模块注册中...");
                            return Observable.just(new AuthResult(feature));
                        }
                    }
                    throw new RuntimeException("请求错误");
                })
                .subscribe(new Observer<>() {
                    @Override
                    public void onCompleted() {
                        String icc_id = Phone.getIccId(context);
                        kvStore.encode(KVKeys.KEY_ENROLLED_ICC_ID, icc_id);
                        CommonLogger.info("注册结束");
                        ActivationManager.get().getCallback().onResult(true, "注册成功");
                    }

                    @Override
                    public void onError(Throwable e) {
                        prompt.setValue("注册失败，请点击返回");
                        failure.setValue(true);
                        CommonLogger.error("注册模块失败", e);
                    }

                    @Override
                    public void onNext(AuthResult authResult) {
                        CommonLogger.info("当前注册结果：%s - %b", authResult.getFeature().getFeature(), authResult.isResult());
                    }
                });
    }

    private class MDMConfig {

        @SerializedName("token")
        private String token;
    }
    private class AuthResult {

        private FeaturesResponse.Feature feature;
        private boolean result;

        public AuthResult(FeaturesResponse.Feature feature) {
            this.feature = feature;
        }

        public FeaturesResponse.Feature getFeature() {
            return feature;
        }

        public boolean isResult() {
            return result;
        }

        public void setResult(boolean result) {
            this.result = result;
        }
    }
}
